#pragma once
#include "../Net/RpcConnection.h"
#include "services.pb.h"
#include "SessionSerivce.h"

enum AuthStatus
{
	SS_CONNECTED,
	SS_LOGINED
};


class WorldConnection : public RpcConnection, public RPC::AuthService
{
public:
	explicit WorldConnection(boost::asio::io_service& io_service, 
								ConnectionClosedListener* listerner = NULL);
	~WorldConnection(void);

	virtual void login(::google::protobuf::RpcController* controller,
		const ::RPC::LoginRequest* request,
		::RPC::CommonResponse* response,
		::google::protobuf::Closure* done);

	virtual Connection* span(boost::asio::io_service& io_service, ConnectionClosedListener* listerner)
	{
		WorldConnection* rc = new WorldConnection(io_service,listerner);
		return rc;
	}

protected:
	virtual void onOpen() {  m_status = SS_CONNECTED; }

	virtual void onHandleRequest(RequestHead& rh, ArrayBuffer& buffer);
	virtual void onHandleResponse(ResponseHead& rh, ArrayBuffer& buffer);

	AuthStatus m_status;
	SessionSerivcePtr m_session;
};

typedef boost::shared_ptr<WorldConnection> WorldConnectionPtr;

class CallMethodHandle
{
public:
	CallMethodHandle(::google::protobuf::Service* service, const CallMethodData& dat) : m_service(service),m_dat(dat)
	{

	}

	void operator()(bool bl)
	{
		if (bl)
		{
			m_service->CallMethod(m_dat.methodescr,m_dat.controller,m_dat.request,m_dat.response,m_dat.done);
		}
		else
		{
			m_dat.controller->SetFailed("SessionSerivce already shutdown");
			m_dat.done->Run();
		}
	}

private:
	::google::protobuf::Service* m_service;
	CallMethodData m_dat;
};
